package com.apes.fn.server.workDesk.service;

import com.apes.fn.business.fixedLoss.modle.LossQuotation;
import com.apes.fn.business.fixedLoss.repository.LossQuotationRepository;
import com.apes.fn.server.productReceive.ProductReceiveItem;
import com.apes.fn.server.productReceive.ProductReceiveRepository;
import com.apes.fn.server.productRequire.ProductRequire;
import com.apes.fn.server.productRequire.ProductRequireItem;
import com.apes.fn.server.productRequire.ProductRequireItemRepository;
import com.apes.fn.server.productRequire.ProductRequireRepository;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.model.ServicePlanItem;
import com.apes.fn.server.servicePlan.repository.ServicePlanItemRepository;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.fn.server.workDesk.model.VehicleControlSQLParamEnum;
import com.apes.fn.server.workOrder.model.MaintenanceOrder;
import com.apes.fn.server.workOrder.repository.MaintenanceOrderRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.query.SqlService;
import com.apes.framework.util.Arith;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * @program: apes-server
 * @description:
 * @author: lws
 * @create: 2022-11-03 11:01
 **/
@Service("workDeskVehicleControlService")
public class WorkDeskVehicleControlService extends DomainService{

    @Autowired
    private SqlService sqlService;
    @Autowired
    private ServicePlanRepository servicePlanRepository;
    @Autowired
    private ServicePlanItemRepository servicePlanItemRepository;
    @Autowired
    private LossQuotationRepository lossQuotationRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private ProductRequireRepository productRequireRepository;
    @Autowired
    private ProductReceiveRepository productReceiveRepository;
    @Autowired
    private MaintenanceOrderRepository maintenanceOrderRepository;
    @Autowired
    private ProductRequireItemRepository productRequireItemRepository;

    public static final String TO_BE_INVOICED = "ZK000752"; // 待开单
    public static final String IN_STORE_ID= "ZK000754"; // 在店
    public static final String IN_THE_INNER_ASSOCIATION = "ZK000755"; // 内协中
    public static final String TO_BE_DELIVERED = "ZK000753"; // 待交车
    public static final String UNSETTLED_DELIVERY = "ZK000756"; // 未结算交车
    public static final String STATEMENT_DELIVERY = "ZK000757"; // 结单交车
    public static final String FINISH = "ZK000758"; // 结束


    private interface FunctionByTwoParam<T, P, R > {
        R apply(T t,P p);
    }

    /**
     * 工作台车辆总控首页数据
     * @param request
     * @return
     */
    public Object vehicleControlHomePage(SimpleRequest request){
        JSONObject result = new JSONObject();
        com.alibaba.fastjson.JSONObject jo = request.getJO();
        List<Object> list = new ArrayList<>();
        Object deptId = jo.get("deptId");
        if (deptId instanceof String){
            list.add(deptId);
        }else if (deptId instanceof JSONArray){
            list.addAll((JSONArray) deptId);
        }else if (deptId instanceof com.alibaba.fastjson.JSONArray){
            list.addAll((com.alibaba.fastjson.JSONArray) deptId);
        }else {
            list.add(deptId);
        }
        Map param = new HashMap();
        if (deptId!=null){
            param = MapUtil.mapper("DEPT_ID",list);
        }
        // 总计
        JSONArray total = new JSONArray();
        total.add(queryManager(param,VehicleControlSQLParamEnum.IN_STORE,this::totalDataProcess));
        total.add(queryManager(param,VehicleControlSQLParamEnum.INTERNAL_ASSOCIATION,this::totalDataProcess));
        total.add(queryManager(param,VehicleControlSQLParamEnum.WAIT_PAY_CAR,this::totalDataProcess));
        total.add(queryManager(param,VehicleControlSQLParamEnum.NOT_RETAIL_ORDER_PAY_CAR,this::totalDataProcess));
        result.put("totalData",total);
        // 卡片
        result.put("cardAll",queryManager(param,VehicleControlSQLParamEnum.CARD_DATE,this::cardAllProcess));
        cardAllFilter(jo,result);
        return result;
    }

    public Object vehicleControlHomePageByMerchant(SimpleRequest request){
        com.alibaba.fastjson.JSONObject jo = request.getJO();
        com.alibaba.fastjson.JSONObject param = new com.alibaba.fastjson.JSONObject();
        List<String> allDept = new ArrayList<>();
        com.alibaba.fastjson.JSONArray jsonArray = new com.alibaba.fastjson.JSONArray();
        switch (jo.getString("id")){
            case "all":
                break;
            case "none":
                param.put("NONE","NONE");
                break;
                default:
                    param.put("MERCHANT_ID",jo.getString("id"));
        }

        JSONObject result = new JSONObject();
        // 总计
        JSONArray total = new JSONArray();
        total.add(queryManager(param,VehicleControlSQLParamEnum.IN_STORE,this::totalDataProcess));
        total.add(queryManager(param,VehicleControlSQLParamEnum.INTERNAL_ASSOCIATION,this::totalDataProcess));
        total.add(queryManager(param,VehicleControlSQLParamEnum.WAIT_PAY_CAR,this::totalDataProcess));
        total.add(queryManager(param,VehicleControlSQLParamEnum.NOT_RETAIL_ORDER_PAY_CAR,this::totalDataProcess));
        result.put("totalData",total);
        // 卡片
        result.put("cardAll",queryManager(param,VehicleControlSQLParamEnum.CARD_DATE,this::cardAllProcess));
        cardAllFilter(jo,result);

        return result;
    }

    /**
     * 工作台车辆总控卡片详情数据
     * @param request
     * @return
     */
    public Object vehicleControlCardDetail(SimpleRequest request){
        JSONArray result = new JSONArray();
        com.alibaba.fastjson.JSONObject jo = request.getJO();
        Map param = MapUtil.mapper("DEPT_ID",jo.getString("DEPT_ID"),
                                           "FN_CUSTOMER_EXPAND_ID",jo.getString("FN_CUSTOMER_EXPAND_ID"));
        // 服务方案
        result.addAll((JSONArray)queryManager(param,VehicleControlSQLParamEnum.CARD_SERVICE_PLAN,this::cardPlanProcess));
        // 定损方案
        result.addAll((JSONArray)queryManager(param,VehicleControlSQLParamEnum.CARD_LOSS_QUOTATION,this::cardPlanProcess));
        return MapUtil.mapper("cardDetail",result);
    }

    /**
     * 右边框车辆信息
     * @param request
     * @return
     */
    public Object vehicleControlCarInfo(SimpleRequest request){
        JSONObject result = new JSONObject();
        com.alibaba.fastjson.JSONObject jo = request.getJO();
        Map param = MapUtil.mapper("DEPT_ID",jo.getString("DEPT_ID"),
                "FN_CUSTOMER_EXPAND_ID",jo.getString("FN_CUSTOMER_EXPAND_ID"));
        result.put("carInfo",queryManager(param, VehicleControlSQLParamEnum.CAR_DATE, this::carInfoProcess));
        return result;
    }

    /**
     * 右边框当前消费页签
     * @param request
     * @return
     */
    public Object vehicleControlCurrentConsume(SimpleRequest request){
        com.alibaba.fastjson.JSONObject jo = request.getJO();
        Map param = MapUtil.mapper("DEPT_ID",jo.getString("DEPT_ID"),
                "FN_CUSTOMER_EXPAND_ID",jo.getString("FN_CUSTOMER_EXPAND_ID"));

        JSONObject result = new JSONObject();
        // 方案信息
        JSONArray servicePlanResult = (JSONArray)queryManager(param, VehicleControlSQLParamEnum.SERVICE_PLAN_DETAIL, this::servicePlanProcess);
        // 定损信息
        JSONArray lossQuotationResult = (JSONArray)queryManager(param,VehicleControlSQLParamEnum.LOSS_QUOTATION_DETAIL,this::lossQuotationProcess);

        JSONArray detail = new JSONArray();
        detail.addAll(servicePlanResult);
        detail.addAll(lossQuotationResult);
        result.put("currentConsume",detail);
        // 费用明细参数
        result.put("amountDetail",amountDetail(servicePlanResult,lossQuotationResult));
        return result;
    }

    /**
     * 调用SQL查询
     * @param paramEnum
     * @return
     */
    private JSONArray querySQL(VehicleControlSQLParamEnum paramEnum){
        return sqlService.queryId(paramEnum.getQueryId(), paramEnum.getParam());
    }

    /**
     *
     * @param param  动态入参
     * @param SQLParam
     * @param function  对查询结果操作
     * @return
     */
    private Object queryManager(Map param, VehicleControlSQLParamEnum SQLParam, FunctionByTwoParam<VehicleControlSQLParamEnum,JSONArray,Object> function){
        JSONObject param1 = SQLParam.getParam();
        JSONObject jsonObject = new JSONObject();
        jsonObject.putAll(param);
        jsonObject.putAll(param1);
        JSONArray queryResult = sqlService.queryId(SQLParam.getQueryId(), jsonObject);
        Object apply = function.apply(SQLParam, queryResult);
        return apply;
    }

    private Object commonSQLQuery(VehicleControlSQLParamEnum queryParam,FunctionByTwoParam<VehicleControlSQLParamEnum,JSONArray,Object> function){
        JSONArray queryResult = querySQL(queryParam);
        return function.apply(queryParam,queryResult);
    }

    private JSONArray cardAllProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum,JSONArray queryResult){
        JSONArray newQueryResult = new JSONArray();
        newQueryResult.addAll(queryResult);
        JSONArray result = new JSONArray();
        while (newQueryResult.size()>500){
            JSONArray temp = new JSONArray();
            for (int i = 0; i < 499; i++) {
                temp.add(newQueryResult.remove(0));
            }
            result.addAll(splitResult(temp));
        }
        result.addAll(splitResult(newQueryResult));
        return result;
    }

    private JSONArray splitResult(JSONArray queryResult) {
        if (queryResult.size()<= 0) return new JSONArray();
        String carModelCodes = "";
        for (Object item : queryResult) {
            JSONObject jo = (JSONObject) item;
            jo.put("timeConsume",timeConsume(jo,"CREATE_DATE"));
            switch (jo.getString("STATE")){
                case "待开单":jo.put("STATE","在店");jo.put("msg","暂时没有业务。如需做单请开单!");break;
                case "待交车":jo.put("msg","你太棒了，此车业务已处理完毕，赶紧通知客户取车吧！");break;
            }

            carModelCodes += jo.getString("JEKUN_MODEL_CODE") + ",";
        }
        // 请求app获取logo图片
        Map map = MapUtil.mapper("carModelCode",carModelCodes.substring(0,carModelCodes.length() - 1));
        com.alibaba.fastjson.JSONObject response = com.alibaba.fastjson.JSONObject.parseObject(this.invoke("pi.app.ext", MapUtil.mapper("headers",MapUtil.mapper("method","v1/car/get-brand-data","action","get"),"body",map)));
        com.alibaba.fastjson.JSONArray data = response.getJSONArray("data");
        for (Object item : queryResult) {
            Map jo = (Map) item;
            String jekunModelCode = (String)jo.get("JEKUN_MODEL_CODE");
            if (data==null)break;
            for (Object dataItem : data) {
                Map dataDetail = (Map) dataItem;
                if (dataDetail.get("carModelCode").equals(jekunModelCode)) {
                    String brandLogoUrl = "".equals(dataDetail.get("brandLogoUrl").toString()) ? "assets/tmp/img/home/motorsIcon.png" : dataDetail.get("brandLogoUrl").toString();
                    jo.put("logo",brandLogoUrl);
                    break;
                }
            }
        }
        return queryResult;
    }

    private JSONArray cardPlanProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum,JSONArray queryResult){
        queryResult.stream().forEach(item ->{
            JSONObject jo = (JSONObject) item;
            String tab = jo.getString("TAB");
            String[] split = tab.split(",");
            List<String> stringList = Arrays.stream(split).distinct().collect(Collectors.toList());
            jo.put("TAB", stringList);
        });
        return queryResult;
    }

    private JSONObject totalDataProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum,JSONArray queryResult){
        JSONObject jo = (JSONObject)queryResult.stream().findFirst().orElse(null);
        jo.put("SYS_RID",null);
        jo.put("remark",vehicleControlSQLParamEnum.getRemark());
        return jo;
    }

    private JSONObject carInfoProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum,JSONArray queryResult){
        if (queryResult.size() <= 0) return null;
        JSONObject jo = (JSONObject)queryResult.stream().findFirst().orElse(null);
        jo.put("SYS_RID",null);
        jo.put("customer",MapUtil.mapper("customerName",jo.getString("CUSTOMER_NAME"),
                                            "mobile",jo.getString("MOBILE")));
        Map map = MapUtil.mapper("carModelCode",jo.getString("JEKUN_MODEL_CODE"));
        com.alibaba.fastjson.JSONObject response = com.alibaba.fastjson.JSONObject.parseObject(this.invoke("pi.app.ext", MapUtil.mapper("headers",MapUtil.mapper("method","/v1/car/get-brand-data","action","get"),"body",map)));
        Map data = (Map)response.getJSONArray("data").stream().findFirst().orElse(null);
        String string = data.get("brandLogoUrl").toString();
        String brandLogoUrl = "".equals(string) ? "assets/tmp/img/home/motorsIcon.png" : string;
        jo.put("logo",brandLogoUrl);
        return jo;
    }

    private JSONArray servicePlanProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum,JSONArray queryResult){
        return planProcess(vehicleControlSQLParamEnum,queryResult,this::servicePlanProcess);
    }

    private JSONArray lossQuotationProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum,JSONArray queryResult){
        return planProcess(vehicleControlSQLParamEnum,queryResult,this::lossQuotationProcess);
    }

    private JSONArray planProcess(VehicleControlSQLParamEnum vehicleControlSQLParamEnum, JSONArray queryResult, Function<JSONArray,JSONArray> function){
        if(queryResult.size() <= 0) return queryResult;
        JSONArray result = new JSONArray();
        queryResult = function.apply(queryResult);
        // 根据方案id分组
        Map<String, List<Object>> group = queryResult.stream().collect(groupingBy(item -> ((JSONObject) item).getString("ID")));
        Collection<List<Object>> values = group.values();
        for (List<Object> value : values) {
            JSONObject jo = new JSONObject();
            JSONObject planItem = value.stream().map(item -> (JSONObject) item).findFirst().orElse(null);
            jo.put("TIME_CONSUME",timeConsume(planItem,"CREATE_DATE"));
            jo.put("ID",planItem.getString("ID"));
            jo.put("STATE",planItem.getString("STATE"));
            jo.put("CREATE_DATE",planItem.getString("CREATE_DATE"));
            jo.put("CREATOR",planItem.getString("CREATOR"));
            jo.put("Items",value);
            // 获取该方案的工时与配件价格
            double workDetail = getSumByProductGroup("20",value);
            double partDetail = getSumByProductGroup("10",value);
            jo.put("workDetail",workDetail);
            jo.put("partDetail",partDetail);
            result.add(jo);
        }
        // 排序，未收款完成的排在前面
        return sortByState(result,"OTHER_STATE","收款完成");
    }

    private JSONArray servicePlanProcess(JSONArray queryResult){
//        List<String> ids = queryResult.stream().map(item -> {
//            return ((JSONObject) item).getString("ITEM_ID");
//        }).collect(Collectors.toList());
//        List<ServicePlanItem> servicePlanItems = servicePlanItemRepository.findAll(JpaDsl.toCriteria("id", "in", ids));
        JSONArray resultTemp = new JSONArray();
        // 方案明细字段处理
        queryResult.stream().forEach(item ->{
            JSONObject jo = (JSONObject)item;
//            servicePlanItems.stream().forEach(servicePlanItem -> {
//                if (servicePlanItem.getId().equals(jo.getString("ITEM_ID"))){
//                    jo.put("WORK_STATE",servicePlanItem.getStateName());
//                }
//            });
            if("null".equals(jo.getString("WORK_STATE_DATE"))) jo.put("WORK_STATE_DATE","--");
            if("null".equals(jo.getString("WORK_STATE"))) jo.put("WORK_STATE","--");
            servicePlanState(jo);
            resultTemp.add(jo);
        });
        return resultTemp;
    }

    private JSONArray lossQuotationProcess(JSONArray queryResult){
        JSONArray resultTemp = new JSONArray();
        // 方案明细字段处理
        queryResult.stream().forEach(item ->{
            JSONObject jo = (JSONObject)item;
            if("null".equals(jo.getString("WORK_STATE_DATE"))) jo.put("WORK_STATE_DATE","--");
            lossQuotationState(jo);
            resultTemp.add(jo);
        });
        return resultTemp;
    }

    private JSONArray sortByState(JSONArray result, String... stateSorts) {
        JSONArray newResult = new JSONArray();
        for (String stateSort : stateSorts) {
            newResult.addAll(result.stream().filter(item ->{
                JSONObject planJo = (JSONObject) item;
                String planState = planJo.getString("STATE");
                if (stateSort.equals("OTHER_STATE") && isNotStateSort(planState,stateSorts)) return true;
                if (stateSort.equals(planState)) return true;
                return false;
            }).collect(Collectors.toList()));
        }
        return newResult;
    }

    private boolean isNotStateSort(String planState,String... stateSorts) {
        for (String stateSort : stateSorts) {
            if (stateSort.equals(planState)) return false;
        }
        return true;
    }

    private void servicePlanState(JSONObject jo){
        Date stateDate = new Date();
        ServicePlan servicePlan = servicePlanRepository.findOne(jo.getString("ID"));
        stateDate = servicePlan.getUpdateDate() != null ? servicePlan.getUpdateDate() : servicePlan.getCreateDate();
        ProductRequireItem productRequireItem = productRequireItemRepository.findOne(jo.getString("STOCK_ITEM_ID"));
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findOne(jo.getString("WORK_ID"));
        if (maintenanceOrder!=null){
            stateDate = maintenanceOrder.getCreateDate().getTime() <= stateDate.getTime() ? stateDate : maintenanceOrder.getCreateDate();
            switch (maintenanceOrder.getWorkState()){
                case "pause":stateDate = maintenanceOrder.getUpdateDate().getTime() <= stateDate.getTime() ? stateDate : maintenanceOrder.getUpdateDate();
                            break;
                case "working":stateDate = maintenanceOrder.getWorkStartTime().getTime() <= stateDate.getTime() ? stateDate : maintenanceOrder.getWorkStartTime();
                            break;
                case "finish":stateDate = maintenanceOrder.getFinishDate().getTime() <= stateDate.getTime() ? stateDate : maintenanceOrder.getFinishDate();
                            break;
            }
        }
        jo.put("WORK_STATE_DATE",dateFormat(stateDate));
    }

    private void lossQuotationState(JSONObject jo){
        Date stateDate = new Date();
        LossQuotation lossQuotation = lossQuotationRepository.findOne(jo.getString("ID"));
        stateDate = lossQuotation.getUpdateDate() != null ? lossQuotation.getUpdateDate() : lossQuotation.getCreateDate();
        ProductRequireItem productRequireItem = productRequireItemRepository.findOne(jo.getString("STOCK_ITEM_ID"));
        jo.put("STOCK_STATE",0); // 要货数量
        if (productRequireItem != null){
            ProductRequire productRequire = productRequireItem.getProductRequire();
            Date productRequireDate = productRequire.getUpdateDate() != null ? productRequire.getUpdateDate() : productRequire.getCreateDate();
            stateDate = productRequireDate.getTime() <= stateDate.getTime() ? stateDate : productRequireDate;
            String state = productRequire.getState();
            double qtyRequire = productRequireItem.getQtyRequire();
            double qtyEnded = productRequireItem.getQtyEnded();
//            double qtyAssigned = productRequireItem.getQtyAssigned();
//            double qtyArrive = productRequireItem.getQtyArrive();
//            if (state.equals("create")){
//                jo.put("STOCK_STATE","未处理");
//            } else if (state.equals("repeal") || state.equals("approve")){
//                if ((qtyRequire - qtyEnded) > qtyAssigned) jo.put("STOCK_STATE","未配货");
//                if (qtyAssigned > qtyAssigned) jo.put("STOCK_STATE","未到货");
//            } else if (qtyArrive >= (qtyRequire - qtyEnded)){
//                jo.put("STOCK_STATE","已完成");
//            }
            jo.put("STOCK_STATE",qtyRequire - qtyEnded);
        }
        jo.put("WORK_STATE_DATE",dateFormat(stateDate));
    }

    private List<Object> planState(List<Object> value,String servicePlanId){
        ServicePlan servicePlan = servicePlanRepository.findOne(servicePlanId);
        List<ServicePlanItem> servicePlanItems = servicePlan.getServicePlanItems();
        //存在接车
        boolean haveCar= sqlService.queryId("WorkDeskVehicleControl.haveCar",new JSONObject(MapUtil.mapper("FN_CUSTOMER_EXPAND_ID",servicePlan.getFnCustomerExpand().getId()))).size() > 0;
        for (Object o : value) {
            JSONObject jo = (JSONObject) o;
            ServicePlanItem servicePlanItem = servicePlanItemRepository.findOne(jo.getString("ITEM_ID"));
            jo.put("WORK_STATE_DATE",dateFormat(servicePlan.getUpdateDate()));
            switch (servicePlan.getState()){
                case "confirm":confirmState(haveCar,servicePlanItem,jo,servicePlan);break;
                case "qualityTest":jo.put("WORK_STATE",notCar(haveCar,"待收款"));break;
                case "receivables":jo.put("WORK_STATE",notCar(haveCar,"待交车"));break;
                default:confirmBefore(servicePlanId,servicePlanItem,jo,servicePlan);break;
            }
        }
        return value;
    }

    private String dateFormat(Date date){
        if(date == null) return "--";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(date);
    }

    private void confirmState(boolean haveCar,ServicePlanItem servicePlanItem,JSONObject jo,ServicePlan servicePlan){
        jo.put("WORK_STATE_DATE",dateFormat(servicePlan.getConfirmDate()));
        //配件与工时
        if ("10".equals(servicePlanItem.getProduct().getProductGroup().getId())){
            // 根据配件是否为带安查询领用单与外协工单
            if(servicePlanItem.isProductRule()){
                //查询外协工单
                jo.put("WORK_STATE",outerServicePlanItem(servicePlanItem,haveCar,jo));
            }else{
                // 查询领用单
                jo.put("WORK_STATE",productReceiveState(servicePlanItem,haveCar,jo));
            }
        }else{
            MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findAll(JpaDsl.toCriteriaByEq("servicePlanItem.id", servicePlanItem.getId())).get(0);
            switch (maintenanceOrder.getWorkState()){
                case "wait":jo.put("WORK_STATE","待施工");jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getCreateDate()));break;
                case "pause":jo.put("WORK_STATE",notCar(haveCar,"暂停中"));jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getUpdateDate()));break;
                case "working":jo.put("WORK_STATE",notCar(haveCar,"施工中"));jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getWorkStartTime()));break;
                case "finish":jo.put("WORK_STATE",notCar(haveCar,"待质检"));jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getFinishDate()));break;
                default:jo.put("WORK_STATE","待施工");jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getCreateDate()));
            }
        }
        // 查询要货单
        ProductRequireItem productRequireItem = productRequireRepository.findStateNotAndProductId("delete",servicePlanItem.getProduct().getId(),servicePlan.getId());
        if (productRequireItem != null) {
            String stockState = "";
            if(productRequireItem.getQtyAssigned() <= 0) stockState = "未发货";
            if(productRequireItem.getQtyAssigned() > 0) stockState = "未到货";
            if(productRequireItem.getQtyArrive() > 0) stockState = "已到货";
            jo.put("STOCK_STATE",stockState);
            jo.put("WORK_STATE_DATE",dateFormat(productRequireItem.getUpdateDate() == null ? productRequireItem.getCreateDate() : productRequireItem.getUpdateDate()));
        }
    }

    private void confirmBefore(String servicePlanId,ServicePlanItem servicePlanItem,JSONObject jo,ServicePlan servicePlan){
        //查询商品询价单
        JSONArray SPXJD = sqlService.queryId("WorkDeskVehicleControl.SPXJD",
                new JSONObject(MapUtil.mapper("servicePlanId", servicePlanId ,"productId", servicePlanItem.getProduct().getId())));
        if (SPXJD.size() > 1){
            JSONObject SPXJDResult = SPXJD.get(0);
            switch (SPXJDResult.getString("DJZT")){
                case "70":jo.put("WORK_STATE","询价完成");break;
                case "40":jo.put("WORK_STATE","询价退回");break;
                default:jo.put("WORK_STATE","询价中");
            }
        }
        // 价格审核状态
        if(servicePlanItem.getShopOwnerPriceLimit() < servicePlanItem.getPftPriceUnit()){
            switch (servicePlan.getState()){
                case "toPriceAudit":jo.put("WORK_STATE","价格审核中");break;
                case "priceAudit":jo.put("WORK_STATE","价格同意");break;
                case "backPriceAudit":jo.put("WORK_STATE","价格退回");break;
            }
        }
    }

    private String notCar(boolean haveCar,String result){
        return !haveCar ? "未结算交车" : result;
    }

    private String outerServicePlanItem(ServicePlanItem servicePlanItem,boolean haveCar,JSONObject jo){
        if (!"outer".equals(servicePlanItem.getAssistType().getId())) return "待转外协";
        String result = "";
        MaintenanceOrder maintenanceOrder = maintenanceOrderRepository.findByServicePlanItemAndBusinessType(servicePlanItem.getId(), MaintenanceOrder.WORK_ORDER_COMMON);
        if(maintenanceOrder == null) return  "待外协派工";
        jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getUpdateDate() == null ? maintenanceOrder.getCreateDate() : maintenanceOrder.getUpdateDate()));
        switch (maintenanceOrder.getState()){
            case "back": result = "外协退回";break;
            default: result = notCar(haveCar,"已派工");break;
        }
        maintenanceOrder = maintenanceOrderRepository.findByServicePlanItemAndBusinessType(servicePlanItem.getId(), MaintenanceOrder.WORK_ORDER_OUT);
        if(maintenanceOrder == null) return "待外协派工";
        jo.put("WORK_STATE_DATE",dateFormat(maintenanceOrder.getUpdateDate()));
        switch (maintenanceOrder.getState()){
            case "back": result = "重新派工";break;
            case "termination": result = "终止";break;
            default: result = notCar(haveCar,"待质检");break;
        }
        return result;
    }

    private String productReceiveState(ServicePlanItem servicePlanItem,boolean haveCar,JSONObject jo){
        ProductReceiveItem productReceiveItem = productReceiveRepository.findProductReceiveItemByStateNotDeleteAndServicePlanItem(servicePlanItem.getId());
        String result = "";
        if (productReceiveItem == null){
            result = "待领用";
        }else if(productReceiveItem.getQtyReceive() == 0){
            result = "待领用";
        }else if(productReceiveItem.getQtyReceive() < servicePlanItem.getSaleQty()){
            result = notCar(haveCar,"部分领用");
        }else if(productReceiveItem.getQtyReceive() == servicePlanItem.getSaleQty()){
            result = notCar(haveCar,"已领用");
        }
        if (productReceiveItem != null) jo.put("WORK_STATE_DATE",dateFormat(productReceiveItem.getUpdateDate() == null?productReceiveItem.getCreateDate():productReceiveItem.getUpdateDate()));
        return result;
    }

    public void cardAllFilter(com.alibaba.fastjson.JSONObject jo,JSONObject result){
        if (!jo.containsKey("remark")) return;
        String state = jo.getString("remark");
        JSONArray cardAll = (JSONArray) result.get("cardAll");
        List<Object> newCardAll = cardAll.stream().filter(item -> {
            JSONObject cardAllJo = (JSONObject) item;
            if (state.equals("内协中"))
                return cardAllJo.getString("STATE") != null && cardAllJo.getString("STATE").contains("内协");
            return state.equals(cardAllJo.getString("STATE"));
        }).collect(Collectors.toList());
        result.put("cardAll",newCardAll);
    }

    private JSONObject amountDetail(JSONArray servicePlanResult,JSONArray lossQuotationResult){
        JSONObject amountDetail = new JSONObject();
        double planWorkDetail = Arith.round(getSumByPlan("workDetail",servicePlanResult),2);
        double planPartDetail = Arith.round(getSumByPlan("partDetail",servicePlanResult),2);
        double lossWorkDetail = Arith.round(getSumByPlan("workDetail",lossQuotationResult),2);
        double lossPartDetail = Arith.round(getSumByPlan("partDetail",lossQuotationResult),2);
        amountDetail.put("planWorkDetail",planWorkDetail);
        amountDetail.put("planPartDetail",planPartDetail);
        amountDetail.put("lossWorkDetail",lossWorkDetail);
        amountDetail.put("lossPartDetail",lossPartDetail);
        double planTotal = Arith.round(Arith.add(planPartDetail,planWorkDetail),2);
        double lossTotal = Arith.round(Arith.add(lossPartDetail,lossWorkDetail),2);
        amountDetail.put("planTotal", planTotal);
        amountDetail.put("lossTotal", lossTotal);
        amountDetail.put("total", Arith.add(planTotal,lossTotal));
        return amountDetail;
    }

    private double getSumByProductGroup(String productGroupId , List<Object> value){
        return value.stream().filter(item -> ((JSONObject)item).getString("PRODUCT_GROUP").equals(productGroupId)).mapToDouble(valueItem -> {
            JSONObject valueMap = (JSONObject) valueItem;
            return Arith.round(Arith.mul(getDouble(valueMap, "SALE_QTY"), getDouble(valueMap, "PFT_PRICE_UNIT")),2);
        }).sum();
    }

    private double getSumByPlan(String plan , JSONArray planResult){
        return planResult.stream().mapToDouble(item ->{
            JSONObject planMap = (JSONObject) item;
            return getDouble(planMap,plan);
        }).sum();
    }

    private double getDouble(JSONObject jo,String dateName){
        try {
            return jo.getDoubleValue(dateName);
        } catch (Exception e) {
            return 0.0;
        }
    }

    private String timeConsume(JSONObject jo,String dateName){
        try {
            Date date = jo.getDate(dateName);
            return timeConsuming(date);
        } catch (Exception e) {
            return "0天0时";
        }
    }

    /**
     * 计算时间差，转换为天时的格式
     * @param date
     * @return
     */
    private String timeConsuming(Date date){
        Long timeConsume = new Date().getTime() - date.getTime();
        Long day = timeConsume / 86400000;
        Long num = day == 0 ? 0 : (day * 86400000);
        Double hour = Arith.round((timeConsume - num) / 3600000.0,2);
        return day + "天" + hour + "小时";
    }
}
